#include "source/common/common/hex.h"
#include "source/common/network/io_socket_handle_impl.h"
#include "source/common/network/listener_filter_buffer_impl.h"
#include "source/extensions/filters/listener/tls_inspector/tls_inspector.h"

#include "test/common/stats/stat_test_utility.h"
#include "test/mocks/api/mocks.h"
#include "test/mocks/network/mocks.h"
#include "test/mocks/stats/mocks.h"
#include "test/test_common/threadsafe_singleton_injector.h"

#include "gtest/gtest.h"

using testing::_;
using testing::Eq;
using testing::InSequence;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::ReturnNew;
using testing::ReturnRef;
using testing::SaveArg;

namespace Envoy {
namespace Extensions {
namespace ListenerFilters {
namespace TlsInspector {
namespace {

// Test vectors for `JA4` fingerprinting
//
// These are published test vectors which are taken from here:
// https://github.com/FoxIO-LLC/ja4/tree/main/pcap
//
// PCAP* files are converted to their hex equivalents using for this test
//
// Format: {client_name, client_hello_hex, expected_hash}
const std::vector<std::tuple<std::string, std::string, std::string>> JA4_TEST_VECTORS = {
    // Browser Client Hello
    {"Browser-1",
     "1603010200010001fc0303528b4e00213672e534980dfed836dd5b375ab164dcc65ba6a3c87e7e2a1f9d61201bf29"
     "c9dffaa31ed2df524d3a113edb4e6fd3b7fb3d6d57d5d9aafb213e83c420020aaaa130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001936a6a0000000d001200100403080404010503080505010806060"
     "1000000170015000012656467652e6d6963726f736f66742e636f6d000a000a00084a4a001d001700180005000501"
     "00000000000b00020100002b0007069a9a03040303001b0003020002ff010001000033002b00294a4a000100001d0"
     "020c4ce4268d58f0c703855163f4754b883742487a5ce87a6016a30208c18e07f69446900050003026832002d0002"
     "01010023000000170000001200000010000e000c02683208687474702f312e310a0a000100001500c500000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Browser Client Hello
    {"Browser-2",
     "1603010200010001fc0303316ea426465bfa03ba577246969e3744997637636047e7065c6f899b9307cf58202161f"
     "b8a1e1fdee39a04f35ca4c84d5d6feccdab582a826493ed2e4c5a753b6100207a7a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001937a7a0000002b0007066a6a03040303446900050003026832000"
     "b0002010000170000000d00120010040308040401050308050501080606010000001600140000116e796d312d6962"
     "2e61646e78732e636f6d001b00030200020005000501000000000033002b0029fafa000100001d00200f53535009d"
     "e31643835df17a86b4c739984a478ae75b75ac77ddf0ec646d220ff010001000010000e000c02683208687474702f"
     "312e31000a000a0008fafa001d00170018002d0002010100120000002300003a3a000100001500c60000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Browser Client Hello
    {"Browser-3",
     "1603010200010001fc030345b0e945658446fb98136c30e1be82ed4bd81e16d332b9f3317a553fcb88e4262032776"
     "135cd2a213dcd935ee9f471768d714d8a9e3292102e1a2e840f52644b0100204a4a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001934a4a00000000001900170000146c707461672e6c69766570657"
     "2736f6e2e6e65740033002b00291a1a000100001d0020a0a1a353c499704a9b56af77f3f87cfdd287e33009eda54f"
     "9ab9b43fb2f595630010000e000c02683208687474702f312e3100170000ff0100010000120000002b000706dada0"
     "3040303000d0012001004030804040105030805050108060601000a000a00081a1a001d00170018002d0002010100"
     "050005010000000000230000000b00020100446900050003026832001b0003020002eaea000100001500c30000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Chrome with `Cloudflare` QUIC
    {"Chrome-Cloudflare-QUIC",
     "1603010200010001fc0303a8ba73151e99d1a071af2e07e67c8b38f14914d8757d56f0f1d85a5a3372f74120c08eb"
     "52a78fdabf9d36b2bc688a1d2024ac9d39c07fe8d2f8190fe1ca00232640020baba130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001930a0a0000000000180016000013636c6f7564666c6172652d717"
     "569632e636f6d00170000ff01000100000a000a0008eaea001d00170018000b00020100002300000010000e000c02"
     "683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000"
     "033002b0029eaea000100001d002065f7b9167d2fb3022d176527bb5b9649296ce07a0fae416fc279d0789747ca10"
     "002d00020101002b0007063a3a03040303001b00030200024469000500030268328a8a000100001500c4000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // HTTP2 with cookies
    {"HTTP2-with-cookies",
     "1603010200010001fc0303c106cecf9c7816cd12e83fd108c36cc8d0ccbedfa9e3742fc7cc43291f8fb0fe20b97db"
     "fd2e6994cad1c1716a927a0a8e7fc68c1ef247f5eeee56aafd747d38f0500204a4a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f003501000193eaea0000002d000201010012000000000010000e00000b796f7"
     "5747562652e636f6d000b00020100446900050003026832001b0003020002ff010001000033002b00293a3a000100"
     "001d0020ec540d5b827860615cb5bd918e5a1c96a461ef17601b1526f00ba148337f645e000d00120010040308040"
     "401050308050501080606010010000e000c02683208687474702f312e31000500050100000000000a000a00083a3a"
     "001d0017001800170000002b000706fafa03040303002300005a5a000100001500cc0000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // TLS SNI - Facebook
    {"TLS-SNI-Facebook",
     "1603010200010001fc0303e1175f99f5325bc5a50cd584b43c53d514d9817d7bd7fe0206d396be1a6569d22051b1f"
     "b16051e06b6deab7d698aeb2fe2dad0b88369baa16c5ec5e994cdc08dfd00206a6a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f003501000193caca00000033002b0029fafa000100001d0020a237f9a08cfb9"
     "8edfee7cf1203690e88ec8679b0af4ea1f1267b0f4845a3897944690005000302683200170000002d00020101000a"
     "000a0008fafa001d00170018000b00020100ff01000100000d0012001004030804040105030805050108060601002"
     "30000002b000706aaaa03040303001b00030200020005000501000000000000001500130000107777772e66616365"
     "626f6f6b2e636f6d0010000e000c02683208687474702f312e31001200008a8a000100001500c7000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000000000000000000000000000000000000000000000000000000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Apple connection
    {"Apple-Connection",
     "1603010200010001fc030328ebe9dfd7ec1eadf1ba5de56c6ccc1664ebac65057658a6f0e088f9ccbce65520aff0c"
     "5d8a69deed07c2fa824f71171ee0ff5a0ca3f32ac3600d2b8d85733b82a0020aaaa130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001932a2a0000000d001200100403080404010503080505010806060"
     "1000500050100000000002d0002010144690005000302683200120000ff010001000023000000170000000a000a00"
     "087a7a001d0017001800000012001000000d7777772e6170706c652e636f6d0033002b00297a7a000100001d0020d"
     "f6e3cd5ecd63b1f567e0e8a7e8334f21853c8f3670ae7fe5ae8ab65bd3592510010000e000c02683208687474702f"
     "312e31000b00020100001b0003020002002b0007063a3a030403033a3a000100001500ca000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Microsoft connection
    {"Microsoft-Connection",
     "1603010200010001fc030355e6d4888ae6a21d7def6a8ffaa923bfc56439336bb9cc8b2a2f69dbad62f73d20706a1"
     "6cbe8cea1c754122c0dac97915279b9c68107c10317d4eebc3281b5fa0400201a1a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f003501000193caca00000033002b0029caca000100001d00206afc692a70094"
     "fc09e29cf4f7ecd111e222a9d5dd86af833cdf8a44b1b254208000500050100000000000b00020100000000160014"
     "0000117777772e6d6963726f736f66742e636f6d001b000302000200230000002d00020101000d001200100403080"
     "4040105030805050108060601ff01000100446900050003026832002b0007069a9a03040303001700000010000e00"
     "0c02683208687474702f312e3100120000000a000a0008caca001d00170018dada000100001500c60000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // Edge browser connection to Slack
    {"Edge-Slack-Connection",
     "16030102210100021d0303e324ad3940b1fc2faac32dfb616b20ade4da5e229307ccf91cedfd6e17a5617b2094062"
     "214534b45539c73dc7e9534660571aa298b29d37c8653f81c9bf813876e00200a0a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001b45a5a0000000d001200100403080404010503080505010806060"
     "10010000e000c02683208687474702f312e3100000012001000000d6170702e736c61636b2e636f6d000b00020100"
     "00230000446900050003026832ff010001000033002b0029baba000100001d00208fdbbcb9960aadf4c716c17de6b"
     "eefe959125b2c0f9ffb95f620cfee1a8e0b78000a000a0008baba001d00170018002d00020101002b0007066a6a03"
     "0403030005000501000000000017000000120000001b00030200026a6a000100002900eb00c600c00534e03d93445"
     "e10b01a3a73b2186cf74d47163aee499d3704619ee0b74ffc1caa7f088708f4dff06ac42f9df8aaa16e8551d8e206"
     "da1d77b19f9f7e5400b142420b7c8ed0ae8841d58a3cf73da84b7f49b11f93d4a1630276dbec257e6883abd0aa876"
     "eea50f122ddfd506694bb949d38dca486e39a0ef9331a6782bb8392a5bc7395189340732a15909e9c309fc4c7c0bd"
     "4102a78c99979e1eb8dcde030c469c38c3f79cee81c9da56db0ab4a3fe19d54da17bf67fc7efce7bb939a292e7c10"
     "82ac2880021201e639a41e760bacf644eeb7b751c0109159373ffdc666c640b661e2be906aa6c",
     "t13d1516h2_8daaf6152771_9b887d9acb53"},

    // SSH
    {"SSH2-Example-1",
     "16030300c2010000be030364a71a64223ce1ee996c921e63b53327aaed6b6bcc68b0aa741c30c175bb19ae000026c"
     "02cc02bc030c02fc024c023c028c027c00ac009c014c013009d009c003d003c0035002f000a0100006f0000001300"
     "1100000e342e736f70686f73786c2e6e6574000500050100000000000a00080006001d00170018000b00020100000"
     "d001a0018080408050806040105010201040305030203020206010603002300000010000e000c0268320868747470"
     "2f312e3100170000ff01000100",
     "t12d1909h2_d83cc789557e_7af1ed941c26"},

    // SSH
    {"SSH2-Example-2",
     "16030300e5010000e1030364a71a5f70dcffaeaff2320de7f1fd36d671b710ee13b47549c043a728ce3483000026c"
     "02cc02bc030c02fc024c023c028c027c00ac009c014c013009d009c003d003c0035002f000a010000920000003600"
     "340000316d6373322d636c6f756473746174696f6e2d65752d776573742d312e70726f642e68796472612e736f706"
     "86f732e636f6d000500050100000000000a00080006001d00170018000b00020100000d001a001808040805080604"
     "0105010201040305030203020206010603002300000010000e000c02683208687474702f312e3100170000ff01000"
     "100",
     "t12d1909h2_d83cc789557e_7af1ed941c26"},

    // SSH
    {"SSH2-Example-3",
     "16030300e0010000dc030364a71a6456b6985c700f3ec255853855cbe3cb56b866a7dc1a90098ae693599220db3b0"
     "000320a99ad9cc36f1fbf707f67fb588945c078880cb2f67a37dd5749670026c02cc02bc030c02fc024c023c028c0"
     "27c00ac009c014c013009d009c003d003c0035002f000a0100006d00000023002100001e73656c662e6576656e747"
     "32e646174612e6d6963726f736f66742e636f6d000500050100000000000a00080006001d00170018000b00020100"
     "000d001a00180804080508060401050102010403050302030202060106030023000000170000ff01000100",
     "t12d190800_d83cc789557e_7af1ed941c26"},

    // SSH
    {"SSH2-Example-4",
     "16030300b5010000b1030364a71a5d3e802015c7fd7fa34933fb46ef368c80f0a00ae2a32b9095d6860917000026c"
     "02cc02bc030c02fc024c023c028c027c00ac009c014c013009d009c003d003c0035002f000a010000620000001800"
     "16000013757064617465732e6f70656e646e732e636f6d000500050100000000000a00080006001d00170018000b0"
     "0020100000d001a00180804080508060401050102010403050302030202060106030023000000170000ff0100010"
     "0",
     "t12d190800_d83cc789557e_7af1ed941c26"},

    // SSH
    {"SSH2-Example-5",
     "1603010200010001fc030341495fff0d6f0a733c814422c981f05196c66538d3b9becf033f29eba7385b2b20770b6"
     "98ee014a8b0b416b087bf09f7eb4bd9e34cf3eab79d37f13a219c5ad3b800201a1a130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f003501000193aaaa0000001b000302000200170000002300000033002b00296"
     "a6a000100001d0020655fae2c36b01db968ff152b20289b63fb022219ab42e9d8ba504e49f614b703002d00020101"
     "0005000501000000000010000e000c02683208687474702f312e3100120000ff01000100000a000a00086a6a001d0"
     "0170018000d0012001004030804040105030805050108060601000b00020100002b0007067a7a0304030344690005"
     "000302683200000011000f00000c7777772e62696e672e636f6dfafa000100001500cb00000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516h2_8daaf6152771_e5627efa2ab1"},

    // IPv6
    {"IPv6",
     "16030100e8010000e40303858226c04fbaeddef4246093b4cfdab38f9dcfef145360e417686575cac49c7000005cc"
     "030c02cc028c024c014c00a009f006b0039cca9cca8ccaaff8500c400880081009d003d003500c00084c02fc02bc0"
     "27c023c013c009009e0067003300be0045009c003c002f00ba0041c011c00700050004c012c0080016000a00ff010"
     "0005f0000001700150000127777772e636c6f7564666c6172652e636f6d000b00020100000a00080006001d001700"
     "18000d001c001a06010603efef0501050304010403eeeeeded03010303020102030010000e000c026832086874747"
     "02f312e31",
     "t12d4605h2_85626a9a5f7f_aaf95bb78ec9"},

    // TLS Non-ASCII ALPN
    {"TLS-Non-ASCII-ALPN",
     "1603010200010001fc03030f9e38acb9a54a7c6e00e29a70ac2feee180ff76d7f25dca84932a66a42d1e5a20bc58b"
     "92f865e6b9aa4a6371cadcb0afe1da1c0f705209a11d52357f56d5dd9620020aaaa130113021303c02bc02fc02cc0"
     "30cca9cca8c013c014009c009d002f0035010001939a9a0000ff010001000033002b00290a0a000100001d0020cf5"
     "5af2603e92f59eb321779706a18fa6b96b16c16404c2264ed687a59401878002d0002010100050005010000000044"
     "6900050003026832000d00120010040308040401050308050501080606010010000e000c02baad08687474702f312"
     "e3100230000001b0003020002002b0007060a0a0304030300000022002000001d636c69656e747365727669636573"
     "2e676f6f676c65617069732e636f6d00120000000a000a00080a0a001d0017001800170000000b000201006a6a000"
     "100001500ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
     "00000000000",
     "t13d1516baad_8daaf6152771_e5627efa2ab1"},
};

class TlsInspectorJA4Test
    : public testing::TestWithParam<std::tuple<std::string, std::string, std::string>> {
public:
  TlsInspectorJA4Test()
      : cfg_(std::make_shared<Config>(
            *store_.rootScope(),
            envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector())),
        io_handle_(Network::SocketInterfaceImpl::makePlatformSpecificSocket(42, false,
                                                                            absl::nullopt, {})) {}

  void init() {
    filter_ = std::make_unique<Filter>(cfg_);

    EXPECT_CALL(cb_, socket()).WillRepeatedly(ReturnRef(socket_));
    EXPECT_CALL(socket_, ioHandle()).WillRepeatedly(ReturnRef(*io_handle_));
    EXPECT_CALL(dispatcher_,
                createFileEvent_(_, _, Event::PlatformDefaultTriggerType,
                                 Event::FileReadyType::Read | Event::FileReadyType::Closed))
        .WillOnce(
            DoAll(SaveArg<1>(&file_event_callback_), ReturnNew<NiceMock<Event::MockFileEvent>>()));
    buffer_ = std::make_unique<Network::ListenerFilterBufferImpl>(
        *io_handle_, dispatcher_, [](bool) {}, [](Network::ListenerFilterBuffer&) {},
        cfg_->initialReadBufferSize() == 0, cfg_->initialReadBufferSize());
    filter_->onAccept(cb_);
  }

  void mockSysCallForPeek(const std::vector<uint8_t>& client_hello) {
#ifdef WIN32
    EXPECT_CALL(os_sys_calls_, readv(_, _, _))
        .WillOnce(Invoke(
            [&client_hello](os_fd_t fd, const iovec* iov, int iovcnt) -> Api::SysCallSizeResult {
              const size_t amount_to_copy = std::min(iov->iov_len, client_hello.size());
              if (amount_to_copy > 0 && iov->iov_base != nullptr && !client_hello.empty()) {
                memcpy(iov->iov_base, client_hello.data(), amount_to_copy);
              }
              return Api::SysCallSizeResult{ssize_t(amount_to_copy), 0};
            }));
#else
    EXPECT_CALL(os_sys_calls_, recv(42, _, _, MSG_PEEK))
        .WillOnce(Invoke(
            [&client_hello](os_fd_t, void* buffer, size_t length, int) -> Api::SysCallSizeResult {
              const size_t amount_to_copy = std::min(length, client_hello.size());
              if (amount_to_copy > 0 && buffer != nullptr && !client_hello.empty()) {
                memcpy(buffer, client_hello.data(), amount_to_copy);
              }
              return Api::SysCallSizeResult{ssize_t(amount_to_copy), 0};
            }));
#endif
  }

  NiceMock<Api::MockOsSysCalls> os_sys_calls_;
  TestThreadsafeSingletonInjector<Api::OsSysCallsImpl> os_calls_{&os_sys_calls_};
  Stats::TestUtil::TestStore store_;
  ConfigSharedPtr cfg_;
  std::unique_ptr<Filter> filter_;
  Network::MockListenerFilterCallbacks cb_;
  Network::MockConnectionSocket socket_;
  NiceMock<Event::MockDispatcher> dispatcher_;
  Event::FileReadyCb file_event_callback_;
  Network::IoHandlePtr io_handle_;
  std::unique_ptr<Network::ListenerFilterBufferImpl> buffer_;
};

INSTANTIATE_TEST_SUITE_P(JA4TestVectors, TlsInspectorJA4Test, testing::ValuesIn(JA4_TEST_VECTORS));

// Test that `JA4` fingerprinting works correctly with captured Client Hello messages
TEST_P(TlsInspectorJA4Test, JA4FingerprintFromCapturedClientHello) {
  const auto& [client_name, client_hello_hex, expected_ja4] = GetParam();

  // Enable `JA4` fingerprinting
  envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector proto_config;
  proto_config.mutable_enable_ja4_fingerprinting()->set_value(true);
  cfg_ = std::make_shared<Config>(*store_.rootScope(), proto_config);

  init();

  // Convert hex string to bytes
  std::vector<uint8_t> client_hello = Hex::decode(client_hello_hex);
  mockSysCallForPeek(client_hello);

  // Expect the `JA4` fingerprint to be set
  EXPECT_CALL(socket_, setJA4Hash(Eq(expected_ja4))).Times(testing::AtMost(1));
  EXPECT_CALL(socket_, setDetectedTransportProtocol(absl::string_view("tls")))
      .Times(testing::AtMost(1));
  EXPECT_CALL(socket_, detectedTransportProtocol()).Times(::testing::AnyNumber());

  // Use general matchers for ALPN and SNI instead of specific values
  EXPECT_CALL(socket_, setRequestedApplicationProtocols(testing::_)).Times(testing::AtMost(1));
  EXPECT_CALL(socket_, setRequestedServerName(testing::_)).Times(testing::AtMost(1));

  // Trigger the event to copy the client hello message into buffer
  EXPECT_TRUE(file_event_callback_(Event::FileReadyType::Read).ok());
  auto state = filter_->onData(*buffer_);

  // This is only checked for tests that pass processing
  if (state == Network::FilterStatus::Continue) {
    EXPECT_EQ(1, cfg_->stats().tls_found_.value());
  }
}

} // namespace
} // namespace TlsInspector
} // namespace ListenerFilters
} // namespace Extensions
} // namespace Envoy
